home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / com_net / net / mailqueue / mailqueue.c next >
Encoding:
C/C++ Source or Header  |  2000-01-01  |  12.2 KB  |  487 lines

  1. /*
  2. Auto:        sc <file>
  3. Auto:        Protect <file> ADD p
  4. */
  5.  
  6.  
  7. /* $Revision Header built automatically *************** (do not edit) ************
  8. **
  9. ** © Copyright by GuntherSoft
  10. **
  11. ** File             : SnakeSYS:CPrgs/MailQueue/MailQueue.c
  12. ** Created on       : Freitag, 13.01.95 17:12:27
  13. ** Created by       : Kai Iske
  14. ** Current revision : V37.0
  15. **
  16. **
  17. ** Purpose
  18. ** -------
  19. **     Watches your SMTP spool directory for the number of
  20. **     messages queued.
  21. **
  22. ** Revision V37.0
  23. ** --------------
  24. ** created on Freitag, 13.01.95 17:12:27  by  Kai Iske.   LogMessage :
  25. **     --- Initial release ---
  26. **
  27. *********************************************************************************/
  28. #define REVISION "37.0"
  29. #define REVDATE  "13.01.95"
  30. #define REVTIME  "17:12:27"
  31. #define AUTHOR   "Kai Iske"
  32. #define VERNUM   37
  33. #define REVNUM   0
  34.  
  35.  
  36.  
  37. #include    <stdlib.h>
  38. #include    <stdio.h>
  39. #include    <string.h>
  40. #include    <stdarg.h>
  41. #include    <exec/types.h>
  42. #include    <exec/memory.h>
  43. #include    <exec/execbase.h>
  44. #include    <proto/exec.h>
  45. #include    <proto/dos.h>
  46. #include    <proto/intuition.h>
  47. #include    <proto/netsupport.h>
  48. #include    <dos/dos.h>
  49. #include    <dos/dosextens.h>
  50. #include    <dos/notify.h>
  51. #include    <dos/exall.h>
  52. #include    <intuition/intuition.h>
  53.  
  54.  
  55. /**********************************************************************/
  56. /*                           Version String                           */
  57. /**********************************************************************/
  58. static    const    char    Ver[]        = "MailQueue "REVISION" ("REVDATE")\0";
  59.  
  60.  
  61.  
  62.  
  63. /**********************************************************************/
  64. /*                              Template                              */
  65. /**********************************************************************/
  66. static    const    char    Template[]    = "WinX/N,WinY/N,OPENNOW/S";
  67. enum{WINX_ARG, WINY_ARG, OPENNOW_ARG, LAST_ARG};
  68.  
  69.  
  70.  
  71. /**********************************************************************/
  72. /*                            Library base                            */
  73. /**********************************************************************/
  74. struct    DosLibrary        *DOSBase;
  75. struct    IntuitionBase        *IntuitionBase;
  76. struct    NetSupportLibrary    *NetSupportBase;
  77.  
  78.  
  79.  
  80. /**********************************************************************/
  81. /*                        Our notify structure                        */
  82. /**********************************************************************/
  83. struct    NotifyNode
  84. {
  85.     struct    Node        Link;
  86.     struct    NotifyRequest    Notify;
  87.     char            Name[258];
  88. };
  89.  
  90.  
  91.  
  92.  
  93.  
  94. /**********************************************************************/
  95. /*                             Prototypes                             */
  96. /**********************************************************************/
  97. static    LONG    ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB);
  98. static    void    __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...);
  99.  
  100.  
  101.  
  102.  
  103. /**********************************************************************/
  104. /*                       This is the main stuff                       */
  105. /**********************************************************************/
  106. ULONG __saveds MailQueue(void)
  107. {
  108.     struct    ExecBase    *SysBase    = *((struct ExecBase **)0x4L);
  109.     struct    Process        *MyProc        = (struct Process *)SysBase->ThisTask;
  110.     struct    RDArgs        *RDArgs;
  111.     struct    ExAllControl    *EAC;
  112.     struct    ExAllData    *EAB;
  113.     LONG            NotifySig;
  114.     APTR            *Args;
  115.     ULONG            NotifyMask,
  116.                 MySig;
  117.     BOOL            Error        = TRUE;
  118.  
  119.  
  120.         // Ignore startup from WB
  121.  
  122.     if(!(MyProc->pr_CLI))
  123.     {
  124.         struct    Message    *MyMsg;
  125.  
  126.         WaitPort(&MyProc->pr_MsgPort);
  127.         MyMsg = GetMsg(&MyProc->pr_MsgPort);
  128.         Disable();
  129.         ReplyMsg(MyMsg);
  130.         return(10);
  131.     }
  132.  
  133.         // Do the wild thing
  134.  
  135.     if((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  136.     {
  137.         if((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  138.         {
  139.             if((NetSupportBase = (struct NetSupportLibrary *)OpenLibrary("netsupport.library", 1)))
  140.             {
  141.                 if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  142.                 {
  143.                     if((EAB = AllocVec(sizeof(struct ExAllData) * 16, MEMF_CLEAR)))
  144.                     {
  145.                         if((Args = AllocVec(LAST_ARG * sizeof(ULONG), MEMF_CLEAR)))
  146.                         {
  147.                             char    *Entry;
  148.  
  149.                             Entry    = GetConfig(NULL, "SMTPSPOOLDIR", "SMTPSPOOLDIR", "");
  150.  
  151.                             if(Entry && strlen(Entry))
  152.                             {
  153.                                 if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
  154.                                 {
  155.                                     if((NotifySig = AllocSignal(-1)) != -1)
  156.                                     {
  157.                                         struct    List        NotifyList;
  158.                                         struct    NotifyRequest    DirNotify;
  159.                                         struct    NotifyNode    *Notify;
  160.                                         struct    Window        *NotifyWindow    = NULL;
  161.                                         ULONG            NotifyWinSig    = 0,
  162.                                                     WinLeft        = 0,
  163.                                                     WinTop        = 0;
  164.                                         char            WinTitle[80];
  165.                                         BOOL            Initial        = TRUE;
  166.  
  167.                                             // Get arguments
  168.  
  169.                                         if(Args[WINX_ARG])
  170.                                             WinLeft        = *((ULONG *)Args[WINX_ARG]);
  171.  
  172.                                         if(Args[WINY_ARG])
  173.                                             WinTop        = *((ULONG *)Args[WINY_ARG]);
  174.  
  175.                                         if(!Args[OPENNOW_ARG])
  176.                                             Initial        = FALSE;
  177.  
  178.                                             // Set up list of notification requests
  179.  
  180.                                         NewList(&NotifyList);
  181.  
  182.                                             // Init notification for Directory
  183.                                             // and cause initial notification
  184.  
  185.                                         DirNotify.nr_Name                = Entry;
  186.                                         DirNotify.nr_Flags                = NRF_SEND_SIGNAL|NRF_NOTIFY_INITIAL;
  187.                                         DirNotify.nr_stuff.nr_Signal.nr_Task        = MyProc;
  188.                                         DirNotify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  189.  
  190.                                             // Do it
  191.  
  192.                                         if(StartNotify(&DirNotify))
  193.                                         {
  194.                                             Error        = FALSE;
  195.  
  196.                                                 // Get Mask for Notification Signal
  197.  
  198.                                             NotifyMask    = 1 << NotifySig;
  199.  
  200.                                             for(;;)
  201.                                             {
  202.                                                 MySig    = Wait(SIGBREAKF_CTRL_C|NotifyMask|NotifyWinSig);
  203.  
  204.                                                     // Quit now
  205.  
  206.                                                 if(MySig & SIGBREAKF_CTRL_C)
  207.                                                     break;
  208.  
  209.                                                     // Anything has changed within the dir
  210.  
  211.                                                 if(MySig & NotifyMask)
  212.                                                 {
  213.                                                     LONG            Number;
  214.  
  215.                                                         // Rescan directory and set up new
  216.                                                         // notifications for files within the dir
  217.                                                         // Create appropriate Window title
  218.  
  219.                                                     if((Number = ScanDir(Entry, &NotifyList, NotifySig, EAC, EAB)) != -1)
  220.                                                         SPrintF(WinTitle, "%ld Message(s) queued", Number);
  221.                                                     else
  222.                                                         strcpy(WinTitle, "Couldn`t get information");
  223.  
  224.                                                         // Update window?
  225.  
  226.                                                     if(NotifyWindow || Number > 0 || Initial)
  227.                                                     {
  228.                                                             // Window not opened yet?
  229.  
  230.                                                         if(!NotifyWindow)
  231.                                                         {
  232.                                                             struct    Screen    *WB    = LockPubScreen(NULL);
  233.  
  234.                                                                 // Open window
  235.  
  236.                                                             if(WB)
  237.                                                             {
  238.                                                                 if((NotifyWindow = OpenWindowTags(NULL,
  239.                                                                     WA_Left,    WinLeft,
  240.                                                                     WA_Top,        WinTop,
  241.                                                                     WA_Width,    (WB->RastPort.TxWidth * 40),
  242.                                                                     WA_Height,    (WB->RastPort.TxHeight + 3),
  243.                                                                     WA_Flags,    WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET,
  244.                                                                     WA_IDCMP,    IDCMP_CHANGEWINDOW|IDCMP_CLOSEWINDOW,
  245.                                                                     WA_PubScreen,    WB,
  246.                                                                     WA_Title,    WinTitle,
  247.                                                                 TAG_DONE)))
  248.                                                                     NotifyWinSig    = 1 << NotifyWindow->UserPort->mp_SigBit;
  249.  
  250.                                                                 UnlockPubScreen(NULL, WB);
  251.                                                             }
  252.                                                         }
  253.                                                         else
  254.                                                             SetWindowTitles(NotifyWindow, WinTitle, (char *)~0);
  255.  
  256.                                                         Initial    = FALSE;
  257.                                                     }
  258.                                                 }
  259.  
  260.                                                     // Signal from window?
  261.  
  262.                                                 if(MySig & NotifyWinSig)
  263.                                                 {
  264.                                                     struct    IntuiMessage    *Msg;
  265.                                                     BOOL            Close    = FALSE;
  266.  
  267.                                                     while((Msg = (struct IntuiMessage *)GetMsg(NotifyWindow->UserPort)))
  268.                                                     {
  269.                                                         if(Msg->Class == IDCMP_CLOSEWINDOW)
  270.                                                             Close    = TRUE;
  271.                                                         else if(Msg->Class == IDCMP_CHANGEWINDOW)
  272.                                                         {
  273.                                                             WinLeft    = NotifyWindow->LeftEdge;
  274.                                                             WinTop    = NotifyWindow->TopEdge;
  275.                                                         }
  276.  
  277.                                                         ReplyMsg((struct Message *)Msg);
  278.                                                     }
  279.  
  280.                                                     if(Close)
  281.                                                     {
  282.                                                         CloseWindow(NotifyWindow);
  283.                                                         NotifyWindow    = NULL;
  284.                                                         NotifyWinSig    = 0;
  285.                                                     }
  286.                                                 }
  287.                                             }
  288.  
  289.                                                 // Close window
  290.  
  291.                                             if(NotifyWindow)
  292.                                                 CloseWindow(NotifyWindow);
  293.  
  294.                                                 // Kill Notifications
  295.  
  296.                                             while((Notify = (struct NotifyNode *)RemHead(&NotifyList)))
  297.                                             {
  298.                                                 EndNotify(&Notify->Notify);
  299.                                                 FreeVec(Notify);
  300.                                             }
  301.  
  302.                                                 // End Dir Notification
  303.  
  304.                                             EndNotify(&DirNotify);
  305.                                         }
  306.                                         else
  307.                                             FPuts(Output(), "MailQueue : Couldn`t launch Notification\n");
  308.  
  309.                                         FreeSignal(NotifySig);
  310.                                     }
  311.                                     else
  312.                                         FPuts(Output(), "MailQueue : Couldn`t allocate Signal\n");
  313.  
  314.                                     FreeArgs(RDArgs);
  315.                                 }
  316.                                 else
  317.                                     PrintFault(IoErr(), "MailQueue ");
  318.                             }
  319.                             else
  320.                                 FPuts(Output(), "MailQueue : SMTPSPOOLDIR settings not found\n");
  321.  
  322.                             FreeVec(Args);
  323.                         }
  324.                         else
  325.                             PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  326.  
  327.                         FreeVec(EAB);
  328.                     }
  329.                     else
  330.                         PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  331.  
  332.                     FreeDosObject(DOS_EXALLCONTROL, EAC);
  333.                 }
  334.                 else
  335.                     PrintFault(ERROR_NO_FREE_STORE, "MailQueue ");
  336.  
  337.                 CloseLibrary((struct Library *)NetSupportBase);
  338.             }
  339.             else
  340.                 FPuts(Output(), "MailQueue : Couldn`t open netsupport.library\n");
  341.  
  342.             CloseLibrary((struct Library *)IntuitionBase);
  343.         }
  344.         else
  345.             FPuts(Output(), "MailQueue : Couldn`t open intuition.library\n");
  346.  
  347.         CloseLibrary((struct Library *)DOSBase);
  348.     }
  349.  
  350.     if(Error)
  351.         return(10);
  352.     else
  353.         return(0);
  354. }
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363. /**********************************************************************/
  364. /*              Scan the directory for the "D.#?" files               */
  365. /**********************************************************************/
  366. static LONG ScanDir(char *DirName, struct List *NotifyList, ULONG NotifySig, struct ExAllControl *EAC, struct ExAllData *EAB)
  367. {
  368.     struct    NotifyNode    *Notify;
  369.     struct    ExAllData    *EAD;
  370.     BPTR            DirLock;
  371.     char            Pattern[32];
  372.     LONG            Number        = -1;
  373.     BOOL            Scanning;
  374.  
  375.  
  376.         // First stop all pending notifications
  377.  
  378.     while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  379.     {
  380.         EndNotify(&Notify->Notify);
  381.         FreeVec(Notify);
  382.     }
  383.  
  384.         // Create pattern for files (Message files start with "D.")
  385.  
  386.     if(ParsePatternNoCase("D.#?", Pattern, 32) != -1)
  387.     {
  388.             // Scan directory
  389.  
  390.         if((DirLock = Lock(DirName, ACCESS_READ)))
  391.         {
  392.             EAC->eac_LastKey    = 0;
  393.             EAC->eac_MatchString    = Pattern;
  394.             EAC->eac_MatchFunc    = 0;
  395.  
  396.             Number        = 0;
  397.  
  398.             do
  399.             {
  400.                 Scanning    = ExAll(DirLock, EAB, (16 * sizeof(struct ExAllControl)), ED_NAME, EAC);
  401.  
  402.                 if(!Scanning && (IoErr() != ERROR_NO_MORE_ENTRIES))
  403.                     Number    = -1;
  404.  
  405.                 if(EAC->eac_Entries == 0)
  406.                     Scanning    = FALSE;
  407.                 else if(Number != -1)
  408.                 {
  409.                     EAD    = EAB;
  410.  
  411.                     do
  412.                     {
  413.                             // Create new notification for file found
  414.  
  415.                         if((Notify = AllocVec(sizeof(struct NotifyNode), MEMF_CLEAR)))
  416.                         {
  417.                             Number++;
  418.  
  419.                                 // Create filename with path
  420.  
  421.                             NameFromLock(DirLock, Notify->Name, 256);
  422.                             AddPart(Notify->Name, EAD->ed_Name, 256);
  423.  
  424.                                 // Set up notification on file
  425.  
  426.                             Notify->Notify.nr_Name                = Notify->Name;
  427.                             Notify->Notify.nr_Flags                = NRF_SEND_SIGNAL;
  428.                             Notify->Notify.nr_stuff.nr_Signal.nr_Task    = FindTask(NULL);
  429.                             Notify->Notify.nr_stuff.nr_Signal.nr_SignalNum    = NotifySig;
  430.  
  431.                                 // Start notification
  432.  
  433.                             if(!StartNotify(&Notify->Notify))
  434.                             {
  435.                                     // Error -> Abort and free memory of node
  436.  
  437.                                 Number    = -1;
  438.                                 FreeVec(Notify);
  439.                                 break;
  440.                             }
  441.                             else
  442.                             {
  443.                                     // Add node to list
  444.  
  445.                                 AddTail(NotifyList, (struct Node *)Notify);
  446.                             }
  447.                         }
  448.                         else
  449.                             Number    = -1;
  450.  
  451.                         EAD    = EAD->ed_Next;
  452.                     } while(EAD && Number != -1);
  453.                 }
  454.             } while(Scanning && Number != -1);
  455.  
  456.             UnLock(DirLock);
  457.         }
  458.     }
  459.  
  460.         // Error?!?! Kill requests
  461.  
  462.     if(Number == -1)
  463.     {
  464.         while((Notify = (struct NotifyNode *)RemHead(NotifyList)))
  465.         {
  466.             EndNotify(&Notify->Notify);
  467.             FreeVec(Notify);
  468.         }
  469.     }
  470.  
  471.     return(Number);
  472. }
  473.  
  474.  
  475.  
  476.  
  477. /**********************************************************************/
  478. /*                         My special sprintf                         */
  479. /**********************************************************************/
  480. static void __stdargs SPrintF(STRPTR buffer, STRPTR formatString,...)
  481. {
  482.     va_list varArgs;
  483.     va_start(varArgs,formatString);
  484.     RawDoFmt(formatString,varArgs,(void (*)())(void (*))"\x16\xC0\x4E\x75",buffer);
  485.     va_end(varArgs);
  486. }
  487.